#include <EEPROM.h>
#include "EmonLib.h"             // Include Emon Library
#include <Tone.h>


EnergyMonitor emon1;             // Create an instance

int status;
int doorbellcount = 0;
int buttonState = 0;
int contactState = 0;
int DBelladdr = 0;

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

int  val = 0; 
char code[10]; 
String tagcode = "0000000000"; 
int bytesread = 0; 
#include <SoftwareSerial.h>
#define rxPin 8
#define txPin 9

SoftwareSerial RFID = SoftwareSerial(rxPin,txPin); 

int SongCount = 0;
Tone tone1;
#define OCTAVE_OFFSET 0
int notes[] = { 
  0,
  NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
  NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
  NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
  NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};
char *song = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6";
#define DoorContact 7
#define DBellSND 5
#define DBellBTN 4
#define DBellLED 3
#define DLOCK 12
#define GAS A5
#define SensorPin1      0
int rawData1;  // variables for sensor1 data
int rawData2;  // variables for sensor1 data
int flash = 0;
boolean LEDSTATE = 0;
unsigned long lastflash;
unsigned long tagwait;
void setup()
{  
  doorbellcount = EEPROM.read(DBelladdr);
  pinMode(DoorContact,INPUT);
  pinMode(DBellSND, OUTPUT);
  pinMode(DBellBTN, INPUT);
  pinMode(DBellLED, OUTPUT);
  pinMode(DLOCK,OUTPUT);
  pinMode(GAS, INPUT);
  digitalWrite(DoorContact, HIGH);
  digitalWrite(DBellLED, HIGH);
  tone1.begin(DBellSND);  
  digitalWrite(DLOCK,LOW);         

  Serial.begin(9600);
  
  pinMode(11,OUTPUT);   // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin 
  digitalWrite(11, LOW);                  // Activate the RFID reader
  RFID.begin(2400);
  
  emon1.voltage(1, 138.5, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(0, 85.8);       // Current: input pin, calibration.
//  inputString.reserve(200);

  lastflash = millis();
  tagwait = millis();
}
boolean lastbuttonstate = LOW;


void loop()
{

  if (flash == 1){
    if(millis() > (lastflash + 400)){
      digitalWrite(DBellLED, LEDSTATE);
      LEDSTATE = !LEDSTATE;
      lastflash = millis();
    }
  }
   if(RFID.available() > 0) {          // if data available from reader 
    if((val = RFID.read()) == 10) {   // check for header 
      bytesread = 0; 
      while(bytesread<10) {              // read 10 digit code 
        if( RFID.available() > 0) { 
          val = RFID.read(); 
          if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading 
            break;                       // stop reading 
          } 
          code[bytesread] = val;         // add the digit           
          bytesread++;                   // ready to read next digit  
        } 
      } 
      if(bytesread == 10) {              // if 10 digit read is complete 
//        Serial.print("TAG code is: ");   // possibly a good TAG 
//        Serial.println(code);            // print the TAG code 
        tagcode = code;
        digitalWrite(11, HIGH);      
        tagwait = millis();
      } else {
       tagcode = "0000000000"; 
      }
    }
   }else{
           tagcode = "0000000000";  
   }
      bytesread = 0;
   
if(millis() > (tagwait + 1500)){
  digitalWrite(11, LOW); 
}

  
  contactState = digitalRead(DoorContact); 
  buttonState = digitalRead(DBellBTN);
  Serial.print(rawData1);	// Smoothed Watts
  Serial.print(",");
  Serial.print(rawData2);	// Smoothed Volts
  Serial.print(",");
  Serial.print(buttonState);
  Serial.print(",");
  Serial.print(contactState);
  Serial.print(",");
  Serial.print(tagcode);
  Serial.print(",");  
  Serial.print(analogRead(GAS));
  Serial.println(",");  
if(flash == 0){
  if (buttonState == HIGH) 
  {
    if (lastbuttonstate != buttonState){
      lastbuttonstate = HIGH;
//      Serial.println("DoorBell Pressed");
      digitalWrite(DBellLED, LOW);
      play_rtttl(song);
      digitalWrite(DBellLED, HIGH);
      doorbellcount ++;
      EEPROM.write(DBelladdr, doorbellcount);
    }
  }
  else{
    lastbuttonstate = LOW; 
  }
}
  emon1.calcVI(20,2000);         // Calculate all. No.of wavelengths, time-out

  rawData1 = emon1.apparentPower;
  rawData2 = emon1.Vrms;


 
  }  



#define isdigit(n) (n >= '0' && n <= '9')

void play_rtttl(char *p)
{
  // Absolutely no error checking in here
  delay(10);
  byte default_dur = 4;
  byte default_oct = 6;
  int bpm = 63;
  int num;
  long wholenote;
  long duration;
  byte note;
  byte scale;

  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)

  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'

  // get default duration
  if(*p == 'd')
  {
    p++; 
    p++;              // skip "d="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }

//  Serial.print("ddur: "); 
//  Serial.println(default_dur, 10);

  // get default octave
  if(*p == 'o')
  {
    p++; 
    p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }

//  Serial.print("doct: "); 
//  Serial.println(default_oct, 10);

  // get BPM
  if(*p == 'b')
  {
    p++; 
    p++;              // skip "b="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }

//  Serial.print("bpm: "); 
//  Serial.println(bpm, 10);

  // BPM usually expresses the number of quarter notes per minute
  wholenote = (60 * 1000L / bpm) * 4;  // this is the time for whole note (in milliseconds)

//  Serial.print("wn: "); 
//  Serial.println(wholenote, 10);


  // now begin note loop
  while(*p)
  {
    // first, get note duration, if available
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }

    if(num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after

      // now get the note
    note = 0;

    switch(*p)
    {
    case 'c':
      note = 1;
      break;
    case 'd':
      note = 3;
      break;
    case 'e':
      note = 5;
      break;
    case 'f':
      note = 6;
      break;
    case 'g':
      note = 8;
      break;
    case 'a':
      note = 10;
      break;
    case 'b':
      note = 12;
      break;
    case 'p':
    default:
      note = 0;
    }
    p++;

    // now, get optional '#' sharp
    if(*p == '#')
    {
      note++;
      p++;
    }

    // now, get optional '.' dotted note
    if(*p == '.')
    {
      duration += duration/2;
      p++;
    }

    // now, get scale
    if(isdigit(*p))
    {
      scale = *p - '0';
      p++;
    }
    else
    {
      scale = default_oct;
    }

    scale += OCTAVE_OFFSET;

    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)

    // now play the note

    if(note)
    {
//      Serial.print("Playing: ");
//      Serial.print(scale, 10); 
//      Serial.print(' ');
//      Serial.print(note, 10); 
//      Serial.print(" (");
//      Serial.print(notes[(scale - 4) * 12 + note], 10);
//      Serial.print(") ");
//      Serial.println(duration, 10);
      tone1.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
    }
    else
    {
//      Serial.print("Pausing: ");
//      Serial.println(duration, 10);
//      delay(duration);
    }
  }
//  Serial.println("Done Playing");
}



void serialEvent() {
   while (Serial.available()) {
     // get the new byte:
     char inChar = (char)Serial.read(); 
     // add it to the inputString:
     
     // if the incoming character is a newline, set a flag
     // so the main loop can do something about it:
     if (inChar == '\n') {
       stringComplete = true;
     } else{
     inputString += inChar;
     }
   }
   
   if (stringComplete) {
//     Serial.println(inputString); 
     if (inputString == "open"){
        digitalWrite(DLOCK,HIGH);         
       }
     if (inputString == "close"){
        digitalWrite(DLOCK,LOW);         
       }
     if (inputString == "ledflash"){
        flash = 1;         
       }
       if (inputString == "ledstop"){
        flash = 0; 
      //  Serial.println("ledstop");
        digitalWrite(DBellLED, HIGH);         
       }
       if(inputString == "ledon"){
  //       Serial.println("ledon");
        digitalWrite(DBellLED, HIGH); 
       }
       if(inputString == "ledoff"){
         digitalWrite(DBellLED, LOW);
    //     Serial.println("LEDoff");
       }
     // clear the string:
     inputString = "";
     stringComplete = false;
   }

}
